﻿//////////////////////////////////////////////////////////////////////////////
//
// Copyright © 1998-2024 Glodon Company Limited.
//
// Licensed under the MIT License
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the “Software”),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//////////////////////////////////////////////////////////////////////////////

// std headers

// qt headers
#include <QUuid>
#include <QFileInfo>
#include <QXmlStreamReader>
#include <QDir>

// gcmp headers

// custom headers
#include "SelectingFileItem.h"

#include "GCSGacZipUtils.h"
#include "PathUtils.h"
#include "ICategory.h"
#include "AppService.h"
#include "TranslatorManager.h"


#include "EnableCompileWarning_The_LAST_IncludeInCpp.h" 
namespace gmepgcs
{
    SelectingFileItem::SelectingFileItem(const QString filePath, QObject *parent /*= nullptr*/) :
        QObject(parent),
        m_id(QUuid::createUuid().toString()),
        m_filePath(filePath),
        m_fileName(),
        m_fileSize(0.0),
        m_isSelected(false),
        m_categoryGuid(),

        m_categoryFullName(),
        m_categoryCode(),
        m_gacProjectAppName(),
        m_gacProjectAppVersion(),
        m_gacProjectAppMainVersion(),
        m_remark(),
        m_isGacProjectAppVersionChecked(false),
        m_isGacCategoryChecked(false),
        m_isCategoryMapped(false)
    {
        Init();
    }

    SelectingFileItem::~SelectingFileItem()
    {

    }

    QString SelectingFileItem::Id() const
    {
        return m_id;
    }

    QString SelectingFileItem::FilePath() const
    {
        return m_filePath;
    }

    QString SelectingFileItem::FileName() const
    {
        return m_fileName;
    }
    
    double SelectingFileItem::FileSize() const
    {
        return m_fileSize;
    }

    QString SelectingFileItem::FileSizeStr(const char & unit, const int & precision) const
    {
        double size = 0.0;

        auto upperUnit = QChar(unit).toUpper();
        if (upperUnit == 'K')
        {
            size = m_fileSize / 1024;
        }
        else
        {
            return QString();
        }

        return QString("%1%2")
            .arg(QString::number(size, 'f', precision))
            .arg(upperUnit);
    }

    QString SelectingFileItem::CategoryFullName() const
    {
        return m_categoryFullName;
    }

    QString SelectingFileItem::Remark() const
    {
        return m_remark;
    }

    std::wstring SelectingFileItem::CategoryCode() const
    {
        return m_categoryCode;
    }

    std::wstring SelectingFileItem::GacProjectAppVersion() const
    {
        return m_gacProjectAppVersion;
    }

    std::wstring SelectingFileItem::GacProjectAppName() const
    {
        return m_gacProjectAppName;
    }

    QString SelectingFileItem::GacProjectAppMainVersion() const
    {
        return m_gacProjectAppMainVersion;
    }

    std::wstring SelectingFileItem::GetCategoryGuid() const
    {
        return m_categoryGuid;
    }

    bool SelectingFileItem::IsSelected() const
    {
        return m_isSelected;
    }

    bool SelectingFileItem::IsSelectable() const
    {
        return m_isGacProjectAppVersionChecked && m_isGacCategoryChecked;
    }

    void SelectingFileItem::SetIsSelected(const bool & isSelected)
    {
        if (!IsSelectable())
        {
            return;
        }

        if (m_isSelected == isSelected)
        {
            return;
        }
        
        m_isSelected = isSelected;
        emit SelectionChanged(m_isSelected);
    }

   
    
    void SelectingFileItem::Init()
    {
        if (!m_filePath.isEmpty())
        {
            // basic file info
            QFileInfo fileInfo(m_filePath);
            m_fileName = fileInfo.fileName();
            m_fileSize = (double)fileInfo.size();

            // gac project app name, gac project app version
            auto gacFilePath = m_filePath.toStdWString();
            std::wstring componentEditorVersion, mergedFamily;
            GacZipUtils::GetProjectAppInfo(gacFilePath, m_gacProjectAppName, m_gacProjectAppVersion, componentEditorVersion, mergedFamily);
            
            // gac project app main version
            if (!m_gacProjectAppVersion.empty())
            {
                auto qGacProjectAppVersion = QString::fromStdWString(m_gacProjectAppVersion);
                auto splits = qGacProjectAppVersion.split(QChar('.'));
                if (splits.size() >= 2)
                {
                    m_gacProjectAppMainVersion = QString("%1.%2").arg(splits[0]).arg(splits[1]);
                }
            }

            // 未获取到版本
            if (m_gacProjectAppMainVersion.isEmpty())
            {
                m_gacProjectAppMainVersion = "— —";

                m_isCategoryMapped = true;
                m_categoryFullName = "— —";

                m_remark = QString::fromStdWString(GBMP_TR(L"构件信息不全，请检查构件版本"));
            }
            // 获取到版本，但高于项目（软件）版本
            else if (CompareVersion(m_gacProjectAppMainVersion, QString::fromStdWString(AppService::Get()->GeFormattedProductVersion())) > 0)
            {
                m_remark = QString::fromStdWString(GBMP_TR(L"构件版本过高"));
            }
            else if (mergedFamily.length() > 0) //这是二三维合并后的构件
            {
                m_remark = QString::fromStdWString(GBMP_TR(L"无法添加二三维合并构件"));
            }
            // 获取到版本，且版本不高于项目（软件）版本，版本校验通过
            else
            {
                m_isGacProjectAppVersionChecked = true;
            }

            // category guid
            m_categoryGuid = GacZipUtils::GetCategoryGuid(gacFilePath);
            
            if (m_categoryGuid == std::wstring())
            {
                m_isCategoryMapped = true;
                m_categoryFullName = "— —";

                if (m_remark.isEmpty())
                {
                    m_remark = QString::fromStdWString(GBMP_TR(L"未检测到分类，请检查构件版本"));
                }
            }
        }
    }

    int SelectingFileItem::CompareVersion(const QString & version1, const QString & version2)
    {
        QChar sep('.');
        auto version1Splits = version1.split(sep);
        auto version2Splits = version2.split(sep);
        auto version1Size = version1Splits.size();
        auto version2Size = version2Splits.size();
        auto count = qMax(version1Size, version2Size);
        
        for (auto i = 0; i < count; ++i)
        {
            auto version1Part = 0;
            auto version2Part = 0;

            if (i < version1Size)
            {
                version1Part = version1Splits[i].toInt();
            }

            if (i < version2Size)
            {
                version2Part = version2Splits[i].toInt();
            }

            if (version1Part > version2Part)
            {
                return 1;
            }
            else if (version1Part < version2Part)
            {
                return -1;
            }
            else
            {
                continue;
            }
        }

        return 0;
    }

}